package com.mjk.common.web.getway.restful.interceptor.type.export.consts;


import cn.hutool.core.exceptions.ExceptionUtil;
import com.mjk.common.base.error.BizException;
import com.mjk.common.base.model.BaseEntity;
import com.mjk.common.base.response.BeeResponse;
import com.mjk.common.tools.conver.abstractor.DefaultConver;
import com.mjk.common.tools.excel.IFileImportAndExport;
import com.mjk.common.tools.excel.type.FileType;
import com.mjk.common.tools.gson.GsonUtils;
import com.mjk.common.tools.logger.BizLogger;
import com.mjk.common.util.*;
import com.mjk.common.web.getway.transfer.GetwayTransfer;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;


public class ExportConver extends DefaultConver {
	private int pageTotal=1;
	private final AtomicInteger pageIndex = new AtomicInteger(0);
	private final GetwayTransfer getWayProtocal;
	IFileImportAndExport fileInstance;
	private final String fileName;
//	List<BaseEntity> target = new ArrayList<BaseEntity>();
	public ExportConver(GetwayTransfer getWayProtocal,String fileName){		
		this.getWayProtocal = getWayProtocal;
		this.fileName = fileName;
		try{
			fileInstance = FileType.getFileImportAndExportByFileName(fileName);
		}catch(Exception e){
			BizLogger.error(e);
		}
	}
	
	/**
	 * 获取导出数据
	 */	
	@Override
	public void converSource(Object obj) {
		if(obj instanceof Map){			
			BeeResponse response = invoker(obj,1);
			if(response.getCode() !=1){//非成功
				throw new BizException(response.getMsg());
			}
			//获取pageNumber
			if(ObjectUtils.isNotEmpty(response.getData())){
				Object pageNumber ;
				Object total;
				if(GsonUtils.isJson(response.getData().toString())){//如果返回是json
					pageNumber = GsonUtils.getValueFromJson(response.getData().toString(), "pageNumber");
					total = GsonUtils.getValueFromJson(response.getData().toString(), "pageTotal");
				}else if(GsonUtils.isJsonArr(response.getData().toString())){
					pageNumber = 0;
					total = GsonUtils.json2List(response.getData().toString()).size();
				}else{					
					pageNumber = ReflectionUtils.getFieldValue(response.getData(),"pageNumber");
					total = ReflectionUtils.getFieldValue(response.getData(),"pageTotal");
				}
				if(ObjectUtils.isNotEmpty(total)){
					this.pageTotal = Integer.parseInt(total.toString());
				}
				putResult2Queue(response);
				if(ObjectUtils.isNotEmpty(pageNumber)){						
					int number = Integer.parseInt(pageNumber.toString());
					//因为第一页已经查询过，从第二页开始
					for(int i=2;i<=number;i++){						
						putResult2Queue(invoker(obj, i));						
					}
				}
			}			
		}else{
			throw new BizException("params is not map");
		}
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public BeeResponse invoker(Object obj,int pageStart){
		Map params = (Map)obj;
		int pageSize = 5000;
		params.put("pageSize", pageSize);
		params.put("pageStart", pageStart);
		Object result = getWayProtocal.invoke(params);		
		if(result instanceof BeeResponse rsp){
			return rsp;
		}else if(result instanceof Map map){
			BeeResponse response = new BeeResponse();
			response.setCode(Integer.valueOf(map.get("code").toString()));
			response.setMsg(ObjectUtils.isEmpty(map.get("msg"))?"":map.get("msg").toString());
			response.setData(map.get("data"));
			return response;
		}else{
			return BeanUtils.toBean(result, BeeResponse.class);
		}
	}
	
	/**
	 * 数据放入队列
     */
	@SuppressWarnings("unchecked")
	private void putResult2Queue(BeeResponse response){
		if(response.getData() instanceof List){
			for(Object item : (List<Object>)response.getData()){
				try {
					queue.put(item);
				} catch (InterruptedException e) {							
					Thread.currentThread().interrupt();
				}
			}
		}else{
			Object list;
			if(response.getData() instanceof String){
				if(GsonUtils.isJson(response.getData().toString())){//如果返回是json
					list = GsonUtils.json2List(GsonUtils.getValueFromJson(response.getData().toString(), "list"));
				}else if(GsonUtils.isJsonArr(response.getData().toString())){
					list = GsonUtils.json2List(response.getData().toString());
				}else{					
					throw new BizException("export date is not json");
				}							
			}else{
				list = ReflectionUtils.getFieldValue(response.getData(), "list");
			}
			if(ObjectUtils.isEmpty(list)){
				return;
			}
			if(list instanceof List){
				for(Object item : (List<Object>)list){
					try {
						queue.put(item);
					} catch (InterruptedException e) {							
						Thread.currentThread().interrupt();
					}
				}
			}
		}
	}
	/**
	 * 获取进度条
     */
	public int getProcess(){
		if(pageTotal == 0){
			return 100;
		}
		return (pageIndex.intValue()*100/pageTotal) ;
	}
	
	public int getProcessWithInr(int index){
		if(pageTotal == 0){
			return 100;
		}
		index = index+1;
		return (index*100/pageTotal) ;
	}
	/**
	 * 写入文件
	 */
	@Override
	public void converTarget(Object o) {
		fileInstance.exportFile((BaseEntity)o, fileName,pageIndex.get(), getProcessWithInr(pageIndex.get()));
		pageIndex.addAndGet(1);
	}
	
	/**
	 * 获取文件的二进制值
     */
	public byte[] getFileByte() {
		while(getProcess()<100){		
			ThreadUtils.sleep(100);
		}
		File f = new File(this.fileName);
		if(!f.exists()) {
			return new byte[0];
		}
		try {
			return FileUtils.getFileByte(this.fileName);
		}catch(Exception e) {
			BizLogger.error("export file except：" + ExceptionUtil.stacktraceToString(e));
			return new byte[0];
		}

	}
}
